<?php
declare(strict_types=1);

namespace app\command;

use app\command\Api\library\Builder;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class Api extends Command
{
    protected static $defaultName = 'api';
    protected static $defaultDescription = '生成API文档';

    protected function configure()
    {
        $this->addOption('url', 'u', InputOption::VALUE_OPTIONAL, 'API URL 前缀', '')
             ->addOption('module', 'm', InputOption::VALUE_REQUIRED, '模块名称', '')
             ->addOption('output', 'o', InputOption::VALUE_OPTIONAL, '输出文件名', '')
             ->addOption('template', 't', InputOption::VALUE_OPTIONAL, '模板文件', '')
             ->addOption('force', 'f', InputOption::VALUE_NONE, '强制覆盖')
             ->addOption('title', 'l', InputOption::VALUE_OPTIONAL, '文档标题', 'API文档');
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $module = $input->getOption('module');
        if (empty($module)) {
            $output->writeln('<error>请指定模块名称</error>');
            return Command::FAILURE;
        }

        try {
            // 获取控制器列表
            $controllers = $this->getControllers($module);
            if (empty($controllers)) {
                $output->writeln('<error>未找到任何控制器</error>');
                return Command::FAILURE;
            }

            // 根据模块名生成输出文件名
            $outputFile = $input->getOption('output');
            if (empty($outputFile)) {
                $outputFile = strtolower($module) . '.html';
            }

            // 配置信息
            $config = [
                'title'     => $input->getOption('title'),
                'template'  => $input->getOption('template') ?: __DIR__ . '/Api/template/template.html',
                'output'    => public_path() . '/' . $outputFile,
                'force'     => $input->getOption('force'),
                'url'       => $input->getOption('url'),
            ];

            // 检查输出文件
            if (is_file($config['output']) && !$config['force']) {
                $output->writeln('<error>文件已存在，使用 --force 覆盖</error>');
                return Command::FAILURE;
            }

            // 获取语言包
            $lang = include __DIR__ . '/Api/lang/zh-cn.php';

            // 生成文档
            $builder = new Builder($controllers);
            $content = $builder->render($config['template'], [
                'lang'   => $lang,
                'config' => $config,
            ]);

            // 确保输出目录存在
            $dir = dirname($config['output']);
            if (!is_dir($dir)) {
                mkdir($dir, 0755, true);
            }

            // 写入文件
            if (file_put_contents($config['output'], $content) === false) {
                throw new \RuntimeException('无法写入文件：' . $config['output']);
            }

            $output->writeln('<info>API文档生成成功：' . $config['output'] . '</info>');
            return Command::SUCCESS;

        } catch (\Exception $e) {
            $output->writeln('<error>' . $e->getMessage() . '</error>');
            return Command::FAILURE;
        }
    }

    protected function getControllers(string $module): array
    {
        // 修改为递归读取所有控制器
        $controllers = [];
        $this->scanControllers(app_path() . "/{$module}/controller", $module, $controllers);
        return $controllers;
    }

    /**
     * 递归扫描控制器
     */
    protected function scanControllers(string $path, string $module, array &$controllers, string $namespace = ''): void
    {
        if (!is_dir($path)) {
            throw new \RuntimeException("模块目录不存在：{$path}");
        }

        $files = scandir($path);
        foreach ($files as $file) {
            if ($file === '.' || $file === '..') {
                continue;
            }

            $fullPath = $path . '/' . $file;
            if (is_dir($fullPath)) {
                // 如果是目录，递归扫描
                $this->scanControllers(
                    $fullPath, 
                    $module, 
                    $controllers, 
                    ($namespace ? $namespace . '\\' : '') . $file
                );
            } elseif (str_ends_with($file, '.php')) {
                // 如果是 PHP 文件
                $className = basename($file, '.php');
                $fullClass = "app\\{$module}\\controller" . 
                            ($namespace ? '\\' . $namespace : '') . 
                            '\\' . $className;

                // 检查是否是控制器类
                if (class_exists($fullClass)) {
                    $reflection = new \ReflectionClass($fullClass);
                    // 只添加非抽象的类
                    if (!$reflection->isAbstract() && !$reflection->isTrait() && !$reflection->isInterface()) {
                        $controllers[] = $fullClass;
                    }
                }
            }
        }
    }
}
